'''
Created on 07/06/2010

@author: Will
'''
from pyglet.gl import *
from pyglet import clock

from objects.entitySpawner import EntitySpawner
import pymunk as pm 
import math


class World(object):

    def __init__(self):
        self.spawner = EntitySpawner(self)
        self.realObjects = []
        self.flyingObjects = []
        self.backgrounObjects=[]
        self.decalObjects = []
        
        self.crosshair = None
        self.nextEntId = 0        
        
        self.objectsLayer =    pyglet.graphics.Batch()
        self.flyingLayer =     pyglet.graphics.Batch()
        self.backgroundLayer = pyglet.graphics.Batch()
        self.decalLayer = pyglet.graphics.Batch()
        
        clock.schedule_interval(self.spawner.spawnRandomEntity,3 )
        pm.init_pymunk()
        
        self.space = pm.Space()
        #self.space.damping = 0.99
        self.space.gravity = (0.0, 0.0)
        self.player = None
        self.cameraFocus = None
                
    def createEnts(self,camera,window):
        self.spawner.spawnEntity(None)
        self.spawner.spawnPlayer()
        self.spawner.createCrosshair(window,camera)
        self.spawner.spawnBackgroundObject()
        self.spawner.spawnCar()
        
        
    def getPlayerIntoOrOut(self,vehicle):
        
        self.oldFocus = self.cameraFocus
        if self.getDistanceFromPlayer(vehicle)<100:
            if self.player in self.realObjects:
                self.remove(self.player)        
                self.cameraFocus = vehicle
                vehicle.isBeingControlled = True
                self.cameraFocus = vehicle
                self.player.isBeingControlled = False
        elif self.player not in self.realObjects:
            self.getOutVehicle(vehicle)
            
            
    def getOutVehicle(self,vehicle):
            self.addPlayer(self.player)
            self.player.setPosition(vehicle.getPosition())
            vehicle.isBeingControlled = False
            self.player.isBeingControlled = True

    def addRealObject(self,obj):
        self.realObjects.append(obj)
        self.space.add(obj.body,obj.shape)
        obj._set_batch(self.objectsLayer)
        
    def addBackgroundObject(self,obj):
        self.backgrounObjects.append(obj)
        obj._set_batch(self.backgroundLayer)
        
    def addDecalObject(self,obj):
        self.decalObjects.append(obj)
        obj._set_batch(self.decalLayer)

    def addFlyingObject(self,obj):
        self.flyingObjects.append(obj)
        obj._set_batch(self.flyingLayer)
                
    def addPlayer(self,obj):
        self.player = obj
        self.cameraFocus = self.player
        self.realObjects.append(obj)
        obj._set_batch(self.objectsLayer)
        self.space.add(obj.body,obj.shape)
    
    def tick(self,keyboard):
        for obj in self.realObjects:
            obj.tick(keyboard)
        for obj in self.flyingObjects:
            obj.tick(keyboard)            
        for obj in self.decalObjects:
            obj.tick()
            if obj.dead:
                self.removeDecal(obj)
                
        self.space.step(1/50.0)
        
    def getCrosshairPosition(self):
        return self.crosshair.getPosition()
    
    def remove(self,obj):
        self.realObjects.remove(obj)
        obj.destroy()
        self.space.remove(obj.shape,obj.body)
        
    def removeDecal(self,obj):
        self.decalObjects.remove(obj)
        obj.destroy()
        

    def draw(self):
        glClear(GL_COLOR_BUFFER_BIT)
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        
        self.backgroundLayer.draw()
        self.decalLayer.draw()
        self.objectsLayer.draw()
        self.flyingLayer.draw()


    def getDistance(self,obj,obj2):
        return math.hypot(obj.x - obj2.x,obj.y-obj2.y)
    
    def getDistanceFromPlayer(self,obj):
        return math.hypot(self.player.x - obj.x,self.player.y-obj.y)
        
    def getObjectsAtCrosshair(self):
        objs = []
        for obj in self.realObjects:
            if obj.isAt(self.crosshair.x,self.crosshair.y):
                objs.append(obj)
        return objs
